package com.engine.ch.util;
import java.io.*;
import java.nio.file.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

public class ZipFileProcessor {
    /**
     * 解压ZIP文件并重命名为指定文件名
     * @param zipFilePath ZIP文件路径
     * @param fileId 文件ID
     * @param targetBasePath 目标基础路径
     * @param fileName 目标文件名
     * @param fileSuffix 文件后缀名
     * @return 重命名后的文件完整路径，失败返回null
     */
    public static String extractAndRenameZipFile(String zipFilePath,
                                                 String fileId,
                                                 String targetBasePath,
                                                 String fileName,
                                                 String fileSuffix) {
        // 构建解压路径
        String extractPath = buildExtractPath(targetBasePath, fileId);

        // 创建解压目录
        File extractDir = new File(extractPath);
        if (!extractDir.exists() && !extractDir.mkdirs()) {
            System.err.println("创建解压目录失败: " + extractPath);
            return null;
        }

        File originalFile = null;
        File renamedFile = null;

        try (ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFilePath))) {
            ZipEntry zipEntry;
            byte[] buffer = new byte[4096];
            int fileCount = 0;

            // 遍历ZIP文件中的条目
            while ((zipEntry = zis.getNextEntry()) != null) {
                String entryName = zipEntry.getName();
                File entryFile = new File(extractPath, entryName);

                // 防止ZIP Slip攻击
                String canonicalPath = entryFile.getCanonicalPath();
                String canonicalExtractPath = extractDir.getCanonicalPath();

                if (!canonicalPath.startsWith(canonicalExtractPath + File.separator)) {
                    throw new SecurityException("检测到ZIP Slip攻击: " + entryName);
                }

                if (zipEntry.isDirectory()) {
                    // 创建目录
                    if (!entryFile.exists() && !entryFile.mkdirs()) {
                        System.err.println("创建目录失败: " + entryFile.getAbsolutePath());
                    }
                } else {
                    // 只处理第一个文件（根据需求，ZIP中应该只有一个文件）
                    if (fileCount > 0) {
                        System.err.println("警告：ZIP文件中包含多个文件，只处理第一个文件");
                        break;
                    }

                    // 创建文件
                    File parentDir = entryFile.getParentFile();
                    if (!parentDir.exists() && !parentDir.mkdirs()) {
                        System.err.println("创建父目录失败: " + parentDir.getAbsolutePath());
                        continue;
                    }

                    try (FileOutputStream fos = new FileOutputStream(entryFile)) {
                        int length;
                        while ((length = zis.read(buffer)) > 0) {
                            fos.write(buffer, 0, length);
                        }
                    }

                    originalFile = entryFile;
                    fileCount++;
                }
                zis.closeEntry();
            }

            if (originalFile == null) {
                System.err.println("ZIP文件中没有找到文件");
                deleteExtractedFolder(extractPath);
                return null;
            }

            // 构建目标文件名
            String targetFileName = buildTargetFileName(fileName, fileSuffix);
            renamedFile = new File(extractPath, targetFileName);

            // 重命名文件
            if (originalFile.renameTo(renamedFile)) {
                System.out.println("文件重命名成功: " + originalFile.getName() + " -> " + renamedFile.getName());
                return renamedFile.getAbsolutePath();
            } else {
                System.err.println("文件重命名失败");
                // 重命名失败，返回原文件路径
                return originalFile.getAbsolutePath();
            }

        } catch (Exception e) {
            System.err.println("解压ZIP文件时发生异常: " + e.getMessage());
            // 解压失败时删除已解压的文件
            deleteExtractedFolder(extractPath);
            return null;
        }
    }

    /**
     * 构建目标文件名
     */
    private static String buildTargetFileName(String fileName, String fileSuffix) {
        return fileName;
    }

    /**
     * 构建解压路径
     */
    private static String buildExtractPath(String targetBasePath, String fileId) {
        // 确保基础路径以分隔符结尾
        if (!targetBasePath.endsWith(File.separator)) {
            targetBasePath += File.separator;
        }

        // 使用文件ID和时间戳创建唯一目录名
        String timestamp = String.valueOf(System.currentTimeMillis());
        String extractDir = "extract_" + fileId + "_" + timestamp;
        return targetBasePath + extractDir;
    }

    /**
     * 删除解压的文件夹
     */
    public static boolean deleteExtractedFolder(String extractPath) {
        if (extractPath == null) {
            return true;
        }

        try {
            Path path = Paths.get(extractPath);
            if (Files.exists(path)) {
                // 递归删除目录和文件
                Files.walk(path)
                        .sorted((a, b) -> b.compareTo(a)) // 先删除文件，再删除目录
                        .forEach(p -> {
                            try {
                                Files.delete(p);
                                System.out.println("删除: " + p);
                            } catch (IOException e) {
                                System.err.println("删除文件失败: " + p + ", 错误: " + e.getMessage());
                            }
                        });
                System.out.println("成功删除解压目录: " + extractPath);
                return true;
            } else {
                System.out.println("解压目录不存在: " + extractPath);
                return true;
            }
        } catch (Exception e) {
            System.err.println("删除解压目录时发生异常: " + e.getMessage());
            return false;
        }
    }
}